package com.zj.utils;

import com.zj.exception.BuilderException;
import com.zj.mapping.DynamicSqlSource;
import com.zj.mapping.MappedStatement;
import com.zj.mapping.SqlCommandType;
import com.zj.mapping.SqlSource;
import org.dom4j.Document;
import org.dom4j.Element;

import java.util.List;
import java.util.Locale;
import java.util.Properties;

public class XMLMapperBuilder {
    protected final Configuration cfg;
    private Document document;
    private String resource;
    private String nameSpace;


    public XMLMapperBuilder(Document document,Configuration cfg,String resource) {
        this.cfg=cfg;
        this.resource=resource;
        this.document=document;
    }

    public void parse() {
        //这里resource是xml文件
        if (!cfg.isResourceLoaded(resource)) {
            Element root=document.getRootElement();
            this.nameSpace=root.attributeValue("namespace");
            if(nameSpace==null){
                throw new BuilderException("no nameSpace of reource "+resource);
            }
            List<Element> sqlElements=root.elements();
            for(Element child:sqlElements){
                parseStatementNode(child);
            }
            cfg.addLoadedResource(resource);
            bindMapperForNamespace();
        }

    }

    private void parseStatementNode(Element child){
        SqlCommandType commandType= SqlCommandType.valueOf(child.getName() .toUpperCase(Locale.ENGLISH));;
        String methodName=child.attributeValue("id");
        String resultType=child.attributeValue("resultType");
        Class type=cfg.getTypeAliasRegistry().resolveAlias(resultType);
        String sql=child.getText();
        SqlSource sqlSource=new DynamicSqlSource(cfg,sql);
        String id=this.nameSpace+"."+methodName;
        MappedStatement statement=new MappedStatement(id,commandType,sqlSource,type,cfg,resource);
        cfg.addMappedStatement(statement);
    }



    private void bindMapperForNamespace(){
        if (nameSpace != null) {
            Class<?> boundType = null;
            try {
                boundType = Resources.classForName(nameSpace);
            } catch (ClassNotFoundException e) {
                //ignore, bound type is not required
            }
            if (boundType != null) {
                if (!cfg.hasMapper(boundType)) {
                    // Spring may not know the real resource name so we set a flag
                    // to prevent loading again this resource from the mapper interface
                    // look at MapperAnnotationBuilder#loadXmlResource
                    cfg.addLoadedResource("namespace:" + nameSpace);
                    cfg.addMapper(boundType);
                }
            }
        }
    }
}
